using System;
using System.Collections;
using System.Data;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.Policy;
using PHSRAG.Security.Enumerations;
using PHSRAG.Utility;
using Utils = PHSRAG.Insight21.InsightUtilities;

namespace PHSRAG.Insight21.FormsManagement
{
    /// <summary>
    /// The Questionnaires page displays all the existing questionnaires and lets the users manage them.
    /// The user can also create new questionnaires from this page
    /// </summary>
    public partial class QuestionnairesPage : BasePage
    {
        #region Constants

        private const bool AscendingSortSequence = true;
        private const string ColumnNameActive = "Active";
        private const string ColumnNameAllowMultiple = "AllowMultiple";
        private const string ColumnNameCategoryMeaning = "CategoryMeaning";
        private const string ColumnNameCategorySequenceNo = "CategorySequenceNo";
        private const string ColumnNameDescription = "Description";
        private const string ColumnNameId = "Id";
        private const string ColumnNameName = "Name";
        private const string ColumnNameTypeMeaning = "TypeMeaning";
        private const string CurrentPageIndexKey = "currentPageIndexKey_9F49250C-F84F-453f-A43B-A9AE8F6BF81B";
        private const string QuestionnaireDataSourceKey = "questionnaireDataSource_9F49250C-F84F-453f-A43B-A9AE8F6BF81B";
        private const string QuestionnairePageKey = "questionnairePageKey_9F49250C-F84F-453f-A43B-A9AE8F6BF81B";
        private const string SortColumnKey = "sortColumn_9F49250C-F84F-453f-A43B-A9AE8F6BF81B";
        private const string SortOrderKey = "sortOrder_9F49250C-F84F-453f-A43B-A9AE8F6BF81B";
        private const string UnselectedDropDownCode = "unselected";
        private const string UnselectedDropDownText = "--Please select a value--";

        #endregion

        #region Instance Variables (Private)

        private ICachePolicy applicationCachePolicy;
        private ICachePolicy cachePolicy;
        private ICachePolicy pageCachePolicy;
        private DataTable pagedResults;
        private Hashtable questionnaireContainer;
        private DataTable questionnaireDataSource;
        private RefCodes refCodes;

        #endregion

        #region Properties

        /// <summary>Gets or sets current page index for the grid</summary>
        private int CurrentPageIndex
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(QuestionnairePageKey) as Hashtable;
                return (h == null || h[CurrentPageIndexKey] == null) ? 0 : (int) h[CurrentPageIndexKey];
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(QuestionnairePageKey) as Hashtable ?? new Hashtable();
                h[CurrentPageIndexKey] = value;
                questionnaires.CurrentPageIndex = value;
                pageCachePolicy.Cache(QuestionnairePageKey, h);
            }
        }

        /// <summary>
        /// Gets or sets the name of the column on which the grid is sorted
        /// </summary>
        private string SortColumn
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(QuestionnairePageKey) as Hashtable;
                return (h == null || h[SortColumnKey] == null) ? ColumnNameName : (string) h[SortColumnKey];
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(QuestionnairePageKey) as Hashtable ?? new Hashtable();
                h[SortColumnKey] = value;
                pageCachePolicy.Cache(QuestionnairePageKey, h);
            }
        }

        /// <summary>
        /// Gets or sets the order of the sort
        /// </summary>
        private bool SortAscending
        {
            get
            {
                Hashtable h = pageCachePolicy.GetCachedObject(QuestionnairePageKey) as Hashtable;
                return (h == null || h[SortOrderKey] == null) ? true : (bool) h[SortOrderKey];
            }
            set
            {
                Hashtable h = pageCachePolicy.GetCachedObject(QuestionnairePageKey) as Hashtable ?? new Hashtable();
                h[SortOrderKey] = value;
                pageCachePolicy.Cache(QuestionnairePageKey, h);
            }
        }

        #endregion

        #region Events (page)

        /// <summary>
        /// Loads the page, retrieves the refcodes for questionnaire types and categories from the cache based on application cache policy
        /// Loads all questionnaires into a hashtable with id as the key and questionnaire object as the value and binds them to the grid. 
        /// All the questionnaires loaded are stored in cache.
        /// </summary>
        /// <param name="sender">Sender of the event</param>
        /// <param name="e">Event arguments</param>
        protected void OnPageLoad(object sender, EventArgs e)
        {
            try
            {
                if (header.ModuleName == InsightUtilities.Constants.Modules.Admin)
                {
                    if (adminSubNavigation.SelectedTab == "Animals Management")
                    {
                        adminAnimalsSubNavigation.Visible = true;
                        adminHumansSubNavigation.Visible = false;
                        coiSubNavigation.Visible = false;
                        adminAnimalsSubNavigation.SelectedLink = "Forms Management";
                    }
                    else if (adminSubNavigation.SelectedTab == "Humans Management")
                    {
                        adminHumansSubNavigation.Visible = true;
                        adminAnimalsSubNavigation.Visible = false;
                        coiSubNavigation.Visible = false;
                        adminHumansSubNavigation.SelectedLink = "Forms Management";
                    }
                }
                else if (header.ModuleName == InsightUtilities.Constants.Modules.COI)
                {
                    coiSubNavigation.Visible = true;
                    adminAnimalsSubNavigation.Visible = false;
                    adminHumansSubNavigation.Visible = false;
                    coiSubNavigation.SelectedLink = "Forms Management";
                }

                breadCrumb.Add(" Forms Management",
                    Settings.GetKeyValue("SubNavigation.Admin.humansURL", ""),
                    Settings.GetKeyValue("BreadCrumb.SummaryPageLevel", 1));

                annunciator.Message = string.Empty;

                refCodes = (RefCodes) applicationCachePolicy.GetCachedObject(RefCodes.CacheKey);

                if (!Page.IsPostBack && postbackGuard.IsValid)
                {
                    ArrayList questionnaireTypes = refCodes.GetRefCodes(Constants.QuestionnaireType.Domain);
                    if (questionnaireTypes != null)
                    {
                        int questionnaireTypeCount = questionnaireTypes.Count;

                        questionnaireType.Items.Add(new ListItem(UnselectedDropDownText, UnselectedDropDownCode));
                        for (int i = 0; i < questionnaireTypeCount; ++i)
                        {
                            RefCode refCode = (RefCode) questionnaireTypes[i];
                            questionnaireType.Items.Add(new ListItem(refCode.Meaning, refCode.Code));
                        }
                    }

                    CreateQuestionnairesSource();
                    pageCachePolicy.Cache(QuestionnaireDataSourceKey, questionnaireDataSource);

                    LoadQuestionnaires();
                }
                else
                {
                    questionnaireContainer = (Hashtable) cachePolicy.GetCachedObject(Keys.QuestionnaireObjectsKey);
                    questionnaireDataSource = (DataTable) pageCachePolicy.GetCachedObject(QuestionnaireDataSourceKey);
                }
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error while loading the page";
            }
            finally
            {
                if (coiSubNavigation.Visible)
                {
                    coiSubNavigation.SelectedLink = "Forms Management";
                    coiSubNavigation.AccessLevel = ((UserContext) cachePolicy.GetCachedObject(UserContext.CacheKey)).ModuleRoleBitmask;
                }
            }
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Page Init
        /// </summary>
        /// <param name="e">Arguments of the event</param>
        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
            cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
            applicationCachePolicy = (Policy.ICachePolicy) Application[Policy.Names.ApplicationCachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.header.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnNavigate);
            this.breadCrumb.Navigate += new System.Web.UI.WebControls.CommandEventHandler(this.OnNavigate);
            this.topPager.FirstPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnFirstPage);
            this.topPager.PreviousPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnPreviousPage);
            this.topPager.NextPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnNextPage);
            this.topPager.LastPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnLastPage);
            this.questionnaires.ItemCreated += new System.Web.UI.WebControls.DataGridItemEventHandler(this.OnQuestionnairesItemCreated);
            this.questionnaires.ItemCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.OnQuestionnairesItemCommand);
            this.questionnaires.SortCommand += new System.Web.UI.WebControls.DataGridSortCommandEventHandler(this.OnQuestionnairesSortCommand);
            this.questionnaires.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.OnQuestionnairesItemDataBound);
            this.bottomPager.FirstPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnFirstPage);
            this.bottomPager.PreviousPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnPreviousPage);
            this.bottomPager.NextPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnNextPage);
            this.bottomPager.LastPage += new System.Web.UI.WebControls.CommandEventHandler(this.OnLastPage);
            this.Load += new System.EventHandler(this.OnPageLoad);
        }

        #endregion

        #region Event Handlers (controls)

        /// <summary>
        /// Occurs when the FirstPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the first page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnFirstPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                CurrentPageIndex = 0;

                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the first page.";
            }
        }

        /// <summary>
        /// Occurs when the LastPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the last page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnLastPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                CurrentPageIndex = topPager.PageCount - 1;
                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the last page.";
            }
        }

        /// <summary>
        /// Occurs when the NexttPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the next page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnNextPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                ++CurrentPageIndex;

                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the next page.";
            }
        }

        /// <summary>
        /// Occurs when the PreviousPage hyperlink is clicked on the pager.
        /// The grid is reloaded with the data pertaining to the previous page.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnPreviousPage(object sender, CommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                --CurrentPageIndex;

                BindGrid();
                ManagePagination();
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the previous page.";
            }
        }

        /// <summary>
        /// Only 75 characters of the description are shown in each row. If the description is more than 75 charaters, 
        /// then a tooltip showing the whole description is attached to the cell.
        /// </summary>
        /// <param name="sender">Control which raised the event.</param>
        /// <param name="e">Arguments of the event</param>
        private void OnQuestionnairesItemDataBound(object sender, DataGridItemEventArgs e)
        {
            try
            {
                if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
                {
                    string desc = pagedResults.Rows[e.Item.ItemIndex][ColumnNameDescription].ToString();
                    Label qDescription = (Label) e.Item.FindControl("qDescription");
                    if (desc.Length > 75)
                    {
                        qDescription.Text = string.Format("{0}...", desc.Substring(0, 75));
                        e.Item.Cells[2].ToolTip = desc;
                    }
                    else
                    {
                        qDescription.Text = desc;
                    }
                    Label qAllowMultiple = (Label) e.Item.FindControl("qAllowMultiple");
                    qAllowMultiple.Text = (Convert.ToBoolean(pagedResults.Rows[e.Item.ItemIndex][ColumnNameAllowMultiple])) ? "Yes" : "No";

                    Label active = (Label) e.Item.FindControl("active");
                    active.Text = (Convert.ToBoolean(pagedResults.Rows[e.Item.ItemIndex][ColumnNameActive])) ? "Yes" : "No";
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the questionnaires grid";
            }
        }

        /// <summary>
        /// Navigates to the Versions page after setting up the incoming cache with the selected questionnaire id
        /// </summary>
        /// <param name="source">Control which raised the event.</param>
        /// <param name="e">Arguments of the event</param>
        private void OnQuestionnairesItemCommand(object source, DataGridCommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
                {
                    Hashtable outgoingData = new Hashtable();
                    outgoingData.Add(Keys.QuestionnaireIdKey, ((Label) e.Item.FindControl("questionnaireID")).Text);
                    outgoingData.Add(Keys.FromParentPage, true);
                    pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);
                    Response.Redirect(Settings.GetKeyValue("SubNavigation.Admin.Humans.VersionsURL", "Version.aspx"), false);
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while redirecting to the Questionnaire Versions page.";
            }
        }

        /// <summary>
        /// Checks if any other questionnaire exists with the same name. If not, saves the new questionnaire and adds it to the Questionnaire objects container
        /// </summary>
        /// <param name="sender">The object that raised the event</param>
        /// <param name="e">Arguments of the event</param>
        protected void OnSaveQuestionnaire(object sender, EventArgs e)
        {
            try
            {
                if (postbackGuard.IsValid)
                {
                    string name = questionnaireName.Text.Trim();
                    if (DoesQuestionnaireExist(name))
                    {
                        annunciator.Message = "A Questionnaire with the specified name already exists. Enter another name.";
                        return;
                    }
                    if (questionnaireType.SelectedIndex <= 0)
                    {
                        annunciator.Message = "Please select the questionnaire type";
                        return;
                    }
                    if (questionnaireCategory.SelectedIndex <= 0)
                    {
                        annunciator.Message = "Please select the questionnaire category";
                        return;
                    }

                    Questionnaire questionnaire = new Questionnaire(cachePolicy);
                    questionnaire.Id = 0;
                    questionnaire.Name = name;
                    questionnaire.Description = questionnaireDescription.Text.Trim();
                    questionnaire.Type = questionnaireType.SelectedItem.Value;
                    questionnaire.TypeMeaning = questionnaireType.SelectedItem.Text;
                    questionnaire.Category = questionnaireCategory.SelectedItem.Value;
                    questionnaire.CategoryMeaning = questionnaireCategory.SelectedItem.Text;
                    string sequenceNo = questionnaireCategorySequenceNo.Text.Trim();
                    questionnaire.CategorySequenceNo = (sequenceNo == string.Empty) ? 0 : int.Parse(sequenceNo);
                    questionnaire.AllowMultiple = questionnaireAllowMultiple.Checked;
                    if (header.ModuleName == InsightUtilities.Constants.Modules.Admin)
                    {
                        if (adminSubNavigation.SelectedTab == "Animals Management")
                        {
                            questionnaire.ModuleType = (int) ModuleBit.Animals;
                        }
                        else if (adminSubNavigation.SelectedTab == "Humans Management")
                        {
                            questionnaire.ModuleType = (int) ModuleBit.Humans;
                        }
                    }
                    else if (header.ModuleName == InsightUtilities.Constants.Modules.COI)
                    {
                        questionnaire.ModuleType = (int) ModuleBit.COI;
                    }
                    questionnaire.Save(DataAccess.GetConnectionString());
                    questionnaireContainer.Add(questionnaire.Id, questionnaire);
                    AddQuestionnaireToGridSource(questionnaire);
                    SetDefaultPageSettings();
                    BindGrid();
                    ManagePagination();
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Could not save the Questionnaire.";
            }
        }

        /// <summary>
        /// Cancels the creation of new questionnaire
        /// </summary>
        /// <param name="sender">The object that raised the event</param>
        /// <param name="e">Arguments of the event</param>
        protected void OnCancelQuestionnaire(object sender, EventArgs e)
        {
            try
            {
                SetDefaultPageSettings();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Clears controls involved in creating a new questionnaire and displays the UI for creating a questionnaire
        /// </summary>
        protected void OnCreateQuestionnaire(object sender, EventArgs e)
        {
            try
            {
                questionnairesPanel.Visible = false;
                questionnaireName.Text = string.Empty;
                questionnaireDescription.Text = string.Empty;
                questionnaireCategorySequenceNo.Text = "0";
                questionnaireType.SelectedIndex = 0;
                questionnaireCategory.Items.Clear();
                createQuestionnairePanel.Visible = true;
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Loads categories for the selected type
        /// </summary>
        /// <param name="sender">The object that raised the event</param>
        /// <param name="e">Arguments of the event</param>
        protected void OnQuestionnaireTypeSelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                questionnaireCategory.Items.Clear();
                if (questionnaireType.SelectedIndex > 0)
                {
                    LoadCategories(questionnaireType.SelectedValue);
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the categories for the selected questionnaire type.";
            }
        }

        /// <summary>
        /// Constructs and caches a hashtable of data for use by the page to which nagivation leads
        /// </summary>
        private void OnAdminHumansSubNavigate()
        {
            try
            {
                CurrentPageIndex = 0;
                SortColumn = ColumnNameName;
                SortAscending = true;
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Resets the subnavigation selected link before the header or the breadCrumb performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        private void OnNavigate(object sender, CommandEventArgs e)
        {
            try
            {
                CurrentPageIndex = 0;
                SortColumn = ColumnNameName;
                SortAscending = true;
                adminSubNavigation.Reset();
                adminHumansSubNavigation.Reset();
                coiSubNavigation.Reset();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Event raised when the column headings on a grid are selected
        /// </summary>
        /// <param name="source">The control that raised the event.</param>
        /// <param name="e">Tha arguments associated with the event.</param>
        private void OnQuestionnairesSortCommand(object source, DataGridSortCommandEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                if (e.SortExpression != string.Empty)
                {
                    CurrentPageIndex = 0;
                    SortAscending = (SortColumn == e.SortExpression) ? !SortAscending : AscendingSortSequence;
                    SortColumn = e.SortExpression;
                    BindGrid();
                    ManagePagination();
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while sorting Questionnaires.";
            }
        }

        /// <summary>
        /// Handler for event raised while each data grid item is created.
        /// If the item being created is the data grid header, do the following:
        /// Add the appropriate sort symbol to denote ascending/descending sequence for the current sort column.
        /// This requires us to locate the cell which corresponding to the column within the collection of TableCell
        /// maintained by the DataGridItem which is under creation. That collection is indexed numerically, the value being
        /// the position of the column within the columns collection maintained by the data grid.
        /// One simple way to do this is to create static mapping between the name of the column and its index. However, this
        /// suffers from the shortcoming that if the sequence of columns is changed on the page, the static binding MUST
        /// be changed too. If they get out of sync, we would be sorting on inappropriate columns!
        /// To avoid this, and to render the code independent of how the page gets managed, we will build a Hashtable of
        /// column indeces, keyed by the sort expression of each column. That way, we could do a quick lookup to get the
        /// index of a column and set the sort symbol on that column.
        /// </summary>
        /// <param name="sender">Control which raised the event</param>
        /// <param name="e">Argument associated with the event</param>
        private void OnQuestionnairesItemCreated(object sender, DataGridItemEventArgs e)
        {
            try
            {
                if (!postbackGuard.IsValid)
                {
                    return;
                }
                if (e.Item.ItemType == ListItemType.Header)
                {
                    Label sortSymbol = new Label();
                    sortSymbol.Text = SortAscending ? InsightUtilities.Constants.SortAscendingText : InsightUtilities.Constants.SortDescendingText;
                    sortSymbol.Font.Name = InsightUtilities.Constants.SortSymbolFontName;

                    Hashtable columnMap = new Hashtable();
                    foreach (DataGridColumn column in questionnaires.Columns)
                    {
                        columnMap[column.SortExpression] = questionnaires.Columns.IndexOf(column);
                    }

                    string sortColumn = SortColumn;
                    if (columnMap.ContainsKey(sortColumn))
                    {
                        (e.Item.Cells[(int) columnMap[sortColumn]]).Controls.Add(sortSymbol);
                    }
                }
            }
            catch
            {
                annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
                annunciator.Message = "Error occurred while loading the grid.";
            }
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Displays an error message on the screen to the user with the exception, and all
        /// inner exception messages.
        /// </summary>
        /// <param name="ex">The exception to report on</param>
        private void DisplayExceptionReport(Exception ex)
        {
            annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
            annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
        }

        /// <summary>
        /// Enables or Disables links to other pages of the grid on the pager controls
        /// </summary>
//		private void ManageNavigationLinks()
//		{
//			bottomPager.EnableFirstPage = topPager.EnableFirstPage = 
//				bottomPager.EnablePreviousPage = topPager.EnablePreviousPage = 
//				(questionnaires.CurrentPageIndex != 0);
//
//			bottomPager.EnableLastPage = topPager.EnableLastPage = 
//				bottomPager.EnableNextPage = topPager.EnableNextPage = 
//				(questionnaires.CurrentPageIndex != (topPager.PageCount - 1));
//		}
        /// <summary>
        /// Pagination management
        /// </summary>
        private void ManagePagination()
        {
            int currentPageIndex = CurrentPageIndex;
            questionnaires.CurrentPageIndex = currentPageIndex;


            int startIndex = currentPageIndex*questionnaires.PageSize;
            bottomPager.FirstRecord = topPager.FirstRecord = startIndex + 1;

            int lastRecord = questionnaireDataSource.Rows.Count;
            bottomPager.LastRecord = topPager.LastRecord =
                Math.Min(startIndex + questionnaires.PageSize, lastRecord);

            bottomPager.EnableFirstPage = topPager.EnableFirstPage =
                bottomPager.EnablePreviousPage = topPager.EnablePreviousPage =
                    (questionnaires.CurrentPageIndex != 0);

            bottomPager.EnableLastPage = topPager.EnableLastPage =
                bottomPager.EnableNextPage = topPager.EnableNextPage =
                    (questionnaires.CurrentPageIndex != (topPager.PageCount - 1));
        }

        /// <summary>
        /// Initilize the first record, last record and current page values for the pager controls.
        /// Set the current page index to 0 and manage navigation links.
        /// </summary>
//		private void InitializePager()
//		{
//			bottomPager.FirstRecord = topPager.FirstRecord = 1;
//			bottomPager.LastRecord = topPager.LastRecord = 
//				Math.Min(questionnaires.PageSize, questionnaires.Items.Count);
//			bottomPager.CurrentPage = topPager.CurrentPage = 1;
//			CurrentPageIndex = 0;
//			ManageNavigationLinks();
//		}		
        /// <summary>
        /// Checks if a questionnaire with the specified name already exists in the collection of questionnaires
        /// </summary>
        /// <param name="name">Name of the new questionnaire</param>
        /// <returns>true, if questionnaire with the specified name already exists</returns>
        private bool DoesQuestionnaireExist(string name)
        {
            foreach (Questionnaire o in questionnaireContainer.Values)
            {
                if (o.Name == name)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// The default page setting which displays the list of questionnaires and provides the user with an option to create a new questionnaire (Create Questionnaire button)
        /// </summary>
        private void SetDefaultPageSettings()
        {
            questionnairesPanel.Visible = true;
            createQuestionnairePanel.Visible = false;
        }

        /// <summary>
        /// Binds questionnaire objects to datagrid
        /// </summary>
        private void BindGrid()
        {
            if (questionnaireDataSource.Rows.Count != 0)
            {
                topPager.Visible = bottomPager.Visible = true;
                questionnaires.VirtualItemCount = bottomPager.RecordCount =
                    topPager.RecordCount = questionnaireDataSource.Rows.Count;

                int currentPageIndex = CurrentPageIndex;
                int pageCount = (topPager.RecordCount/questionnaires.PageSize) +
                    (((topPager.RecordCount%questionnaires.PageSize) == 0) ? 0 : 1);
                bottomPager.PageCount = topPager.PageCount = pageCount;
                bottomPager.CurrentPage = topPager.CurrentPage = currentPageIndex + 1;

                DataTable table = GetQuestionnairesForGridPage(currentPageIndex*questionnaires.PageSize, questionnaires.PageSize);

                if (table.Rows.Count == 0)
                {
                    annunciator.Message = "No Questionnaires exist to display";
                    questionnaires.Visible = false;
                    return;
                }
                questionnaires.Visible = true;
                questionnaires.DataSource = table;
                questionnaires.DataBind();
            }
            else
            {
                annunciator.Message = "No Questionnaires exist to display";
                questionnaires.Visible = false;
                return;
            }
        }

        /// <summary>
        /// Gets the questionnaires that need to be displayed for a specific page of the grid
        /// </summary>
        /// <param name="startIndex">The grid's current page first record index</param>
        /// <param name="pageSize">The number of records displayed in a grid's page</param>
        /// <returns>Questionnaires to be displayed in the current page of the grid</returns>
        private DataTable GetQuestionnairesForGridPage(int startIndex, int pageSize)
        {
            pagedResults = questionnaireDataSource.Clone();

            DataView questionnairesView = questionnaireDataSource.DefaultView;
            if (SortColumn == ColumnNameTypeMeaning)
            {
                questionnairesView.Sort = string.Format("{0} {1}, {2} Asc, {3} Asc", SortColumn,
                    (SortAscending ? InsightUtilities.Constants.SortViewAscending : InsightUtilities.Constants.SortViewDescending), ColumnNameCategoryMeaning, ColumnNameCategorySequenceNo);
            }
            else if (SortColumn == ColumnNameCategoryMeaning)
            {
                questionnairesView.Sort = string.Format("{0} {1}, {2} Asc", SortColumn,
                    (SortAscending ? InsightUtilities.Constants.SortViewAscending : InsightUtilities.Constants.SortViewDescending), ColumnNameCategorySequenceNo);
            }
            else
            {
                questionnairesView.Sort = string.Format("{0} {1}", SortColumn,
                    (SortAscending ? InsightUtilities.Constants.SortViewAscending : InsightUtilities.Constants.SortViewDescending));
            }

            for (int m = startIndex, endIndex = Math.Min(questionnairesView.Count, startIndex + pageSize); m < endIndex; ++m)
            {
                pagedResults.ImportRow(questionnairesView[m].Row);
            }
            return pagedResults;
        }

        /// <summary>
        /// Creates a datatable containing the details of all the questionnaires. This table acts as the DataSource for the grid.
        /// The reason behind having a seperate table to bind questionnaires instead of using the already existing hashtable is 
        /// because of the order of objects stored inside the hashtable.
        /// </summary>
        private void CreateQuestionnairesSource()
        {
            questionnaireDataSource = new DataTable();
            questionnaireDataSource.Columns.Add(ColumnNameId, typeof (int));
            questionnaireDataSource.Columns.Add(ColumnNameName);
            questionnaireDataSource.Columns.Add(ColumnNameDescription);
            questionnaireDataSource.Columns.Add(ColumnNameTypeMeaning);
            questionnaireDataSource.Columns.Add(ColumnNameCategoryMeaning);
            questionnaireDataSource.Columns.Add(ColumnNameCategorySequenceNo, typeof (int));
            questionnaireDataSource.Columns.Add(ColumnNameAllowMultiple, typeof (bool));
            questionnaireDataSource.Columns.Add(ColumnNameActive, typeof (bool));
        }

        /// <summary>
        /// Loads questionnaire objects details from hashtable to questionnaireDataSource
        /// </summary>
        private void LoadQuestionnairesSource()
        {
            foreach (Questionnaire q in questionnaireContainer.Values)
            {
                AddQuestionnaireToGridSource(q);
            }
        }

        /// <summary>
        /// Adds a questionnaire to questionnaireDataSource
        /// </summary>
        /// <param name="questionnaire">Questionnaire object</param>
        private void AddQuestionnaireToGridSource(Questionnaire questionnaire)
        {
            DataRow row = questionnaireDataSource.NewRow();
            row[ColumnNameId] = questionnaire.Id;
            row[ColumnNameName] = questionnaire.Name;
            row[ColumnNameDescription] = questionnaire.Description;
            row[ColumnNameTypeMeaning] = questionnaire.TypeMeaning;
            row[ColumnNameCategoryMeaning] = questionnaire.CategoryMeaning;
            row[ColumnNameCategorySequenceNo] = questionnaire.CategorySequenceNo;
            row[ColumnNameAllowMultiple] = questionnaire.AllowMultiple;
            row[ColumnNameActive] = questionnaire.Active;
            questionnaireDataSource.Rows.Add(row);
        }

        /// <summary>
        /// Loads questionnaires from the database, stores them in the cache and binds them to the grid
        /// </summary>
        private void LoadQuestionnaires()
        {
            int moduleType = 0;
            if (header.ModuleName == InsightUtilities.Constants.Modules.Admin)
            {
                if (adminSubNavigation.SelectedTab == "Animals Management")
                {
                    moduleType = (int) ModuleBit.Animals;
                }
                else if (adminSubNavigation.SelectedTab == "Humans Management")
                {
                    moduleType = (int) ModuleBit.Humans;
                }
            }
            else if (header.ModuleName == InsightUtilities.Constants.Modules.COI)
            {
                moduleType = (int) ModuleBit.COI;
            }

            questionnaireContainer = FormsManagement.Questionnaire.GetQuestionnaires(moduleType, cachePolicy);
            cachePolicy.Cache(Keys.QuestionnaireObjectsKey, questionnaireContainer);
            LoadQuestionnairesSource();
            BindGrid();
        }

        /// <summary>
        /// Loads the categories based on the form type selected
        /// </summary>
        /// <param name="selectedTypeValue">refcode for the selected form type</param>
        private void LoadCategories(string selectedTypeValue)
        {
            RefCode refCode = refCodes.GetRefCode(selectedTypeValue);

            string categoryDomainForSelectedType = refCode.Attributes[Constants.QuestionnaireType.CategoryAttribute].ToString();

            ArrayList questionnaireCategories = refCodes.GetRefCodes(categoryDomainForSelectedType);
            if (questionnaireCategories != null)
            {
                int questionnaireCategoryCount = questionnaireCategories.Count;
                questionnaireCategory.Items.Add(new ListItem(UnselectedDropDownText, UnselectedDropDownCode));
                for (int i = 0; i < questionnaireCategoryCount; ++i)
                {
                    refCode = (RefCode) questionnaireCategories[i];
                    questionnaireCategory.Items.Add(new ListItem(refCode.Meaning, refCode.Code));
                }
            }
        }

        #endregion
    }
}